package com.fang.security.security.service;

import com.fang.security.entity.DO.SysUser;
import com.fang.security.entity.bo.security.UserRole;
import com.fang.security.service.security.AuthorityService;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description 自定义权限注解验证
 * @Author Bernie
 * @Date 2024/4/23 15:45
 **/
@Component
public class SecurityPermissionEvaluator implements PermissionEvaluator {
    @Resource
    private AuthorityService authorityService;

    /**
     * hasPermission鉴权方法
     * 这里仅仅判断PreAuthorize注解中的权限表达式
     * 实际中可以根据业务需求设计数据库通过targetUrl和permission做更复杂鉴权
     * 当然targetUrl不一定是URL可以是数据Id还可以是管理员标识等,这里根据需求自行设计
     *
     * @Author Sans
     * @CreateTime 2019/10/6 18:25
     * @Param authentication  用户身份(在使用hasPermission表达式时Authentication参数默认会自动带上)
     * @Param targetUrl  请求路径
     * @Param permission 请求路径权限
     * @Return boolean 是否通过
     */
    @Override
    public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {
        /**
         * TODO
         * targetUrl：访问的url地址，此参数在需要多个权限时使用，使用查询`sys_request_path_permission_relation`表获取该访问需要的多个权限，再一一校验。
         */

        // 获取用户信息
        SysUser sysUser = (SysUser) authentication.getPrincipal();
        // 查询用户权限(这里可以将权限放入缓存中提升效率)
        Set<String> permissions = new HashSet<>();
        List<UserRole> userRoles = authorityService.selectUserRoleByUserID(sysUser.getUserId());
        userRoles.forEach(p -> permissions.add(p.getRoleCode()));
        // 权限对比
        if (permissions.contains(permission.toString())) {
            return true;
        }
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}